/**
 * قȂʒuɂ2̓_ABԂ̋擾
 * 
 * @param {Integer} ax _AxW
 * @param {Integer} ay _AyW
 * @param {Integer} bx _BxW
 * @param {Integer} by _ByW
 * @return {Integer} _ABԂ̋
 */
function GetGapLength( ax, ay, bx, by ){
	return ( ( bx - ax ) ^ 2 + ( by - ay ) ^ 2 ) ^ 0.5;
}

/**
 * _AقȂʒuɂ_Bւ̐Ίpx擾
 * 
 * @param {Integer} ax _AxW
 * @param {Integer} ay _AyW
 * @param {Integer} bx _BxW
 * @param {Integer} by _ByW
 * @return {Integer} _A_Bւ̐Ίpx
 */
function GetGapAngle( ax, ay, bx, by ){
	return atan2( by - ay, bx - ax );
}

/**
 * _A炠鋗AΊpxɂ_BxW擾
 * 
 * @param {Integer} ax        _AxW
 * @param {Integer} gaplength _B܂ł̋
 * @param {Integer} gapangle  _Bւ̐Ίpx
 * @return {Integer} _BxW
 */
function GetGapX( ax, gaplength, gapangle ){
	return ax + gaplength * cos( gapangle );
}

/**
 * _A炠鋗AΊpxɂ_ByW擾
 * 
 * @param {Integer} ay        _AyW
 * @param {Integer} gaplength _B܂ł̋
 * @param {Integer} gapangle  _Bւ̐Ίpx
 * @return {Integer} _ByW
 */
function GetGapY( ay, gaplength, gapangle ){
	return ay + gaplength * sin( gapangle );
}

/**
 * ^ꂽpx0ȏ360ɂĕԂ
 * 
 * @param {Integer} angle px
 * @return {Integer} ꂽpx
 */
function RollAngle( angle ){
	return ( ( angle % 360 ) + 360 ) % 360;
}

/**
 * px␳z[~O֐
 * 
 * @param {Integer} x      ݈ʒuxW
 * @param {Integer} y      ݈ʒuyW
 * @param {Integer} tox    ǔڕWxW
 * @param {Integer} toy    ǔڕWyW
 * @param {Integer} nangle ݂̊px
 * @param {Integer} dangle px␳ʍől
 * @return {Integer} z[~O␳̊px
 */
function AngleSearch( x, y, tox, toy, nangle, dangle ){
	let TargetAngle = atan2( toy - y, tox - x );
	let ICross = cos( nangle - TargetAngle );
	let CCross = cos( dangle );
	
	if( ICross < CCross ){
		let LCross = cos( nangle - dangle - TargetAngle );
		let RCross = cos( nangle + dangle - TargetAngle );
		if( LCross > RCross ){
			nangle -= dangle;
		}else{
			nangle += dangle;
		}
	}else{
		nangle = TargetAngle;
	}
	
	return nangle;
}

/**
 * _(x,y)pxangleňƕǂƂ̌_AˊpԂ
 * 
 * @param {Integer} x     w_xW
 * @param {Integer} y     w_yW
 * @param {Integer} angle px
 * @return {Array} ǂƂ̌_Aˊp[rx,ry,rangle]
 */
function GetReflectData( x, y, angle ){
	let rx = 0;
	let ry = 0;
	let rangle = 0;
	
	// ɂ邽߂̏I_ݒ
	let tox = x + cos( angle ) * 800;	// Kɑ傫lŏI_쐬
	let toy = y + sin( angle ) * 800;	// Kɑ傫lŏI_쐬
	
	// ȗ̂߁Bl̕ϐ錾Ăꍇɂ͏ĂOK
	let MinX = GetClipMinX();
	let MaxX = GetClipMaxX();
	let MinY = GetClipMinY();
	let MaxY = GetClipMaxY();
	
	// ㉺Eɑ΂Ĕs
	let PosU = Collision_Line_Line( x, y, tox, toy, MinX, MinY, MaxX, MinY );
	let PosL = Collision_Line_Line( x, y, tox, toy, MinX, MinY, MinX, MaxY );
	let PosR = Collision_Line_Line( x, y, tox, toy, MaxX, MinY, MaxX, MaxY );
	let PosB = Collision_Line_Line( x, y, tox, toy, MinX, MaxY, MaxX, MaxY );
	
	// ʂɂĂǂ̕ǂŔ˂邩I ㉺ȄŔ肳܂
	if( PosU[ 0 ] != NULL ){
		// ゾ
		rx = PosU[ 0 ];
		ry = PosU[ 1 ];
		rangle = -angle;
	}else if( PosB[ 0 ] != NULL ){
		// 
		rx = PosB[ 0 ];
		ry = PosB[ 1 ];
		rangle = -angle;
	}else if( PosL[ 0 ] != NULL ){
		// 
		rx = PosL[ 0 ];
		ry = PosL[ 1 ];
		rangle = 180 - angle;
	}else if( PosR[ 0 ] != NULL ){
		// E
		rx = PosR[ 0 ];
		ry = PosR[ 1 ];
		rangle = 180 - angle;
	}else{
		// ǂɂ˂ĂȂꍇA_~[ƂČ̒lZbg
		rx = x;
		ry = y;
		rangle = angle;
	}
	
	return [ rx, ry, rangle ];
}

/**
 * (x1,y1)-(x2,y2)Ɛ(x3,y3)-(x4,y4)̌_Ԃ
 * 
 * @param {Integer} x1 1̎n_xW
 * @param {Integer} y1 1̎n_yW
 * @param {Integer} x2 1̏I_xW
 * @param {Integer} y2 1̏I_yW
 * @param {Integer} x3 2̎n_xW
 * @param {Integer} y3 2̎n_yW
 * @param {Integer} x4 2̏I_xW
 * @param {Integer} y4 2̏I_yW
 * @return {Array} 2̌_[x,y] Ȃꍇɂ[NULL,NULL]Ԃ
 */
function Collision_Line_Line( x1, y1, x2, y2, x3, y3, x4, y4 ){
	let f1 = x2 - x1;
	let g1 = y2 - y1;
	let f2 = x4 - x3;
	let g2 = y4 - y3;
	
	let det = ( f2 * g1 ) - ( f1 * g2 );
	
	// det̒l0(2)̏ꍇ_݂Ȃ̂Ŗ߂
	if( det == 0 ){
		return [ NULL, NULL ];
	}else{
		// ȊȌꍇA_vZ
		let dx = x3 - x1;
		let dy = y3 - y1;
		let t1 = ( f2 * dy - g2 * dx ) / det;
		let t2 = ( f1 * dy - g1 * dx ) / det;
		
		// _̒ɑ݂Ȃ琔lvZ
		if( ( 0 <= t1 && t1 <= 1 ) && ( 0 <= t2 && t2 <= 1 ) ){
			let rx = x1 + t1 * f1;
			let ry = y1 + t1 * g1;
			
			return [ rx, ry ];
		}else{
			// _̉ɂꍇA_ȂƂ
			return [ NULL, NULL ];
		}
	}
}

/**
 * l𐮐ɕϊB
 *
 * @param {Integer} no ϊΏېl
 * @return 
 */
function IntToString( no ){
		//߂l̏
		let number = "";
		let numberString = ToString( no );
		//_̑O܂ł𕶎ƂĎ擾ĕԂ
		let i = 0;
		while( i < length( numberString ) ){
				let char = numberString[ i ];
				if( char == '.' ){
					break;
				}
				number = number ~ [ char ];
				i += 1;
		}
		return number;
}

/**
 * l𐮐ɕϊB2
 *
 * @param {Integer} no ϊΏېl
 * @return 
 */
function IntToString2( no ){
	let leng = 0;
	if( no > 0 ){
		leng = truncate( log10(  no ) ) + 1;
	}else if( no == 0 ){
		leng = 1;
	}else{
		leng = truncate( log10( -no ) ) + 2;
	}
	
	let string = ToString( no );
	let number = string[ 0..int( leng ) ];
	
	return number;
}